feat(routes): type callers by schema input; per-program AB4834; validate before typecheck (#748, #752) - #757
Conversation
🦋 Changeset detectedLatest commit: f046cf8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b2f9fd454b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "create-agent-bundle": patch | ||
| --- | ||
|
|
||
| Type route callers by schema input and route components by schema output in the generated `.agent-bundle/routes.d.ts`: `createAppClient().call`, `onToolInput`, `renderRoute`, `invokeMcpTool`, and the contract matrix accept what a caller sends (a `.default()`ed field is optional, a `.transform()`ed field is spelled as the wire carries it), while `ToolRouteProps` keeps the parsed output. A structural schema declaring only `_output` uses it for both. `renderRoute` now parses its input through the route's own `inputSchema` before the component runs and fails with an `invalid-input` harness error on rejected input. `agent-bundle validate` reports `AB4834` once per TypeScript program that imports `agent-bundle/app`, `agent-bundle/test`, `agent-bundle/eval`, or `@agent-bundle/runtime` and omits the generated declaration — following `references` transitively — instead of accepting any one referenced program that includes it. The `mcp-server` and `cli-tool` starters run `agent-bundle validate` inside `npm run typecheck`, so a clean checkout type-checks against current route declarations. (#PR) |
There was a problem hiding this comment.
Replace the placeholder PR reference
The changeset leaves (#PR) as a literal placeholder, so it will be published in the user-facing release notes instead of identifying this change; replace it with the actual PR reference (the commit identifies #748/#752). Repository guidance requires changeset summaries to include the PR number and prohibits implementation-note placeholders.
AGENTS.md reference: AGENTS.md:L167-L168
Useful? React with 👍 / 👎.
|
|
||
| /** Whether one of the program's own source files imports a module the generated declaration augments. */ | ||
| const consumesRegistration = (fileNames: readonly string[]): boolean => | ||
| fileNames.some((fileName) => !fileName.endsWith('.d.ts') && consumerImport.test(ts.sys.readFile(fileName) ?? '')); |
There was a problem hiding this comment.
Inspect transitive source files for AB4834
When a config uses files: ["src/index.ts"] or an equivalently narrow include, and that entry point imports another local module which imports agent-bundle/test, agent-bundle/app, or the runtime, parseJsonConfigFileContent().fileNames contains only the configured root files even though tsc follows the imported module into the program. Scanning only this array therefore reports no AB4834 while the actual program consumes the registration without .agent-bundle/routes.d.ts, leaving route IDs and values loosely typed; consumer detection needs to inspect the semantic program or traverse its imports.
Useful? React with 👍 / 👎.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex first-pass findings, addressed locally:
Also fixed from the failed Examples check: |
… changeset PR number
…based AB4834 consumer detection, include-aware recovery
…Route parses input
…pace-linked declarations do not)
…s (review finding)
…the project's consumer (review finding)
3546536 to
f046cf8
Compare
|
Local gate at |
Closes #748. Closes #752.
What
#752 — caller input vs parsed handler output. The generated
.agent-bundle/routes.d.tsnow derives each route'sinputfrom the schema's_input(what a caller sends) instead of_output.createAppClient().call,onToolInput,renderRoute,invokeMcpTool, and contract-matrix fixtures accept{}forz.object({ limit: z.number().default(10) })and a string for a.transform()ed field;ToolRouteProps<typeof inputSchema>['input']keeps the parsed output. A structural schema declaring only_outputuses it for both (explicit rule, spelled in the generated file).renderRoutenow parses input through the route's owninputSchemaat the same boundary the generated Flight worker does — defaults filled, transforms applied once — and rejects invalid input withinvalid-inputbefore any provider or component runs.LoadedRouteModule.inputSchema.parsereturnsunknown(the parsed props are not part of the registration).#748 — reliable typegen / per-program AB4834.
routeTypesProgramDiagnosticswalksreferencestransitively and reportsAB4834once per program that consumes the registration (a source file importingagent-bundle/app,agent-bundle/test,agent-bundle/eval, or@agent-bundle/runtime) and omits the declaration; build-only projects are left alone; recovery names the include path relative to the offending tsconfig. The documented entry for current declarations before an isolated typecheck isagent-bundle validate(~3s, no bundle): themcp-serverandcli-toolstarters'typecheckis nownpm run validate && tsc, andcheckno longer runs validate twice.Tests
tests/route-caller-input-types.test.ts(integration): clean generated project with a solution-style root (tsconfig.app.jsonbrowser program withlib: DOM,tsconfig.node.jsonserver program).validatepublishes the declaration; both real tsconfig programs type-check viats.parseJsonConfigFileContent;client.call('tool:curator/page', {}),onToolInputwith optional default, transform input as string; negatives (wrong id, missing required, wrong primitive, parsed-number-as-caller) each one error; dropping the declaration from the browser program alone yields oneAB4834on that program; built MCP server round trip applies default/transform once and rejects invalid input before the handler runs (invocation log).tests/route-types-program.test.ts: nested references,excluded declaration, build-only project untouched, recovery path relative to nested tsconfig.tests/route-graph.test.ts:_input-bearing and_output-only structural stand-ins.tests/route-unit/render-route.test.ts:renderRouteapplies the default and rejects{ label: 1 }withinvalid-input.route-register-typegen,generated-route-server,route-contract-importsupdated/green; packed scaffold matrix (mcp-server,cli-tool,minimal) green with the newtypecheckscript.Docs
en+zh:
guide/development/testing.mdx,guide/development/index.mdx,guide/authoring/mcp.mdx;docs/diagnostics.md(AB4834);docs/entry-conventions.md; starter READMEs. No overlap with #754's paths.Gate (current origin/main)
pnpm build && pnpm typecheck && pnpm lint✅ ·pnpm test:unit✅ · route-unit pool (90) ✅ · projection pool (191) ✅ ·test:packed:releasescaffold matrix ✅ · full integration pool +pnpm docs:site:build: running, results appended below.Deslop: pending. Self-review: pending.